home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / tecmo.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  10KB  |  414 lines

  1. /***************************************************************************
  2.  
  3.   video hardware for Tecmo games
  4.  
  5. ***************************************************************************/
  6.  
  7. #include "driver.h"
  8. #include "vidhrdw/generic.h"
  9.  
  10. unsigned char *tecmo_videoram,*tecmo_colorram;
  11. unsigned char *tecmo_videoram2,*tecmo_colorram2;
  12. unsigned char *tecmo_scroll;
  13. size_t tecmo_videoram2_size;
  14.  
  15. static unsigned char *dirtybuffer2;
  16. static struct osd_bitmap *tmpbitmap2,*tmpbitmap3;
  17.  
  18. static int video_type = 0;
  19. /*
  20.    video_type is used to distinguish Rygar, Silkworm and Gemini Wing.
  21.    This is needed because there is a difference in the tile and sprite indexing.
  22. */
  23.  
  24.  
  25.  
  26. /***************************************************************************
  27.  
  28.   Start the video hardware emulation.
  29.  
  30. ***************************************************************************/
  31.  
  32. int tecmo_vh_start(void)
  33. {
  34.     if (generic_vh_start()) return 1;
  35.  
  36.     if ((dirtybuffer2 = malloc(videoram_size)) == 0)
  37.     {
  38.         generic_vh_stop();
  39.         return 1;
  40.     }
  41.     memset(dirtybuffer2,1,videoram_size);
  42.  
  43.     /* the background area is twice as wide as the screen */
  44.     if ((tmpbitmap2 = osd_new_bitmap(2*Machine->drv->screen_width,Machine->drv->screen_height,Machine->scrbitmap->depth)) == 0)
  45.     {
  46.         free(dirtybuffer2);
  47.         generic_vh_stop();
  48.         return 1;
  49.     }
  50.     if ((tmpbitmap3 = osd_new_bitmap(2*Machine->drv->screen_width,Machine->drv->screen_height,Machine->scrbitmap->depth)) == 0)
  51.     {
  52.         osd_free_bitmap(tmpbitmap2);
  53.         free(dirtybuffer2);
  54.         generic_vh_stop();
  55.         return 1;
  56.     }
  57.  
  58.     /* 0x100 is the background color */
  59.     palette_transparent_color = 0x100;
  60.  
  61.     return 0;
  62. }
  63.  
  64. int rygar_vh_start(void)
  65. {
  66.     video_type = 0;
  67.     return tecmo_vh_start();
  68. }
  69.  
  70. int silkworm_vh_start(void)
  71. {
  72.     video_type = 1;
  73.     return tecmo_vh_start();
  74. }
  75.  
  76. int gemini_vh_start(void)
  77. {
  78.     video_type = 2;
  79.     return tecmo_vh_start();
  80. }
  81.  
  82.  
  83.  
  84. /***************************************************************************
  85.  
  86.   Stop the video hardware emulation.
  87.  
  88. ***************************************************************************/
  89. void tecmo_vh_stop(void){
  90.   osd_free_bitmap(tmpbitmap3);
  91.   osd_free_bitmap(tmpbitmap2);
  92.   free(dirtybuffer2);
  93.   generic_vh_stop();
  94. }
  95.  
  96. WRITE_HANDLER( tecmo_videoram_w )
  97. {
  98.     if (tecmo_videoram[offset] != data)
  99.     {
  100.         dirtybuffer2[offset] = 1;
  101.         tecmo_videoram[offset] = data;
  102.     }
  103. }
  104.  
  105. WRITE_HANDLER( tecmo_colorram_w )
  106. {
  107.     if (tecmo_colorram[offset] != data)
  108.     {
  109.         dirtybuffer2[offset] = 1;
  110.         tecmo_colorram[offset] = data;
  111.     }
  112. }
  113.  
  114.  
  115. /***************************************************************************
  116.  
  117.   Draw the game screen in the given osd_bitmap.
  118.   Do NOT call osd_update_display() from this function, it will be called by
  119.   the main emulation engine.
  120.  
  121. ***************************************************************************/
  122.  
  123. void tecmo_draw_sprites( struct osd_bitmap *bitmap, int priority )
  124. {
  125.     int offs;
  126.  
  127.     /* draw all visible sprites of specified priority */
  128.     for (offs = 0;offs < spriteram_size;offs += 8)
  129.     {
  130.         int flags = spriteram[offs+3];
  131.  
  132.  
  133.         if( (flags>>6) == priority )
  134.         {
  135.             int bank = spriteram[offs+0];
  136.             if( bank & 4 )
  137.             { /* visible */
  138.                 int which = spriteram[offs+1];
  139.                 int code;
  140.                 int size = (spriteram[offs + 2] & 3);
  141.                 /* 0 = 8x8 1 = 16x16 2 = 32x32 3 = 64x64 */
  142.                 if (size == 3) continue;    /* not used by these games */
  143.  
  144.                 if( video_type != 0)
  145.                   code = (which) + ((bank&0xf8)<<5); /* silkworm */
  146.                 else
  147.                   code = (which)+((bank&0xf0)<<4); /* rygar */
  148.  
  149.                 if (size == 1) code >>= 2;
  150.                 else if (size == 2) code >>= 4;
  151.  
  152.                 drawgfx(bitmap,Machine->gfx[size+1],
  153.                         code,
  154.                         flags&0xf, /* color */
  155.                         bank&1, /* flipx */
  156.                         bank&2, /* flipy */
  157.  
  158.                         spriteram[offs + 5] - ((flags & 0x10) << 4), /* sx */
  159.                         spriteram[offs + 4] - ((flags & 0x20) << 3), /* sy */
  160.  
  161.                         &Machine->drv->visible_area,
  162.                         priority == 3 ? TRANSPARENCY_THROUGH : TRANSPARENCY_PEN,
  163.                         priority == 3 ? palette_transparent_pen : 0);
  164.             }
  165.         }
  166.     }
  167. }
  168.  
  169. void tecmo_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  170. {
  171.     int offs;
  172.  
  173.  
  174. palette_init_used_colors();
  175.  
  176. {
  177.     int color,code,i;
  178.     int colmask[16];
  179.     int pal_base;
  180.  
  181.  
  182.     pal_base = Machine->drv->gfxdecodeinfo[5].color_codes_start;
  183.  
  184.     for (color = 0;color < 16;color++) colmask[color] = 0;
  185.  
  186.     for (offs = videoram_size - 1;offs >= 0;offs--)
  187.     {
  188.         if (video_type == 2)    /* Gemini Wing */
  189.         {
  190.             code = videoram[offs] + 16 * (colorram[offs] & 0x70);
  191.             color = colorram[offs] & 0x0f;
  192.         }
  193.         else
  194.         {
  195.             code = videoram[offs] + 256 * (colorram[offs] & 0x07),
  196.             color = colorram[offs] >> 4;
  197.         }
  198.  
  199.         colmask[color] |= Machine->gfx[5]->pen_usage[code];
  200.     }
  201.  
  202.     for (color = 0;color < 16;color++)
  203.     {
  204.         if (colmask[color] & (1 << 0))
  205.             palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
  206.         for (i = 1;i < 16;i++)
  207.         {
  208.             if (colmask[color] & (1 << i))
  209.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  210.         }
  211.     }
  212.  
  213.  
  214.     pal_base = Machine->drv->gfxdecodeinfo[4].color_codes_start;
  215.  
  216.     for (color = 0;color < 16;color++) colmask[color] = 0;
  217.  
  218.     for (offs = videoram_size - 1;offs >= 0;offs--)
  219.     {
  220.         if (video_type == 2)    /* Gemini Wing */
  221.         {
  222.             code = tecmo_videoram[offs] + 16 * (tecmo_colorram[offs] & 0x70);
  223.             color = tecmo_colorram[offs] & 0x0f;
  224.         }
  225.         else
  226.         {
  227.             code = tecmo_videoram[offs] + 256 * (tecmo_colorram[offs] & 0x07),
  228.             color = tecmo_colorram[offs] >> 4;
  229.         }
  230.  
  231.         colmask[color] |= Machine->gfx[4]->pen_usage[code];
  232.     }
  233.  
  234.     for (color = 0;color < 16;color++)
  235.     {
  236.         if (colmask[color] & (1 << 0))
  237.             palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
  238.         for (i = 1;i < 16;i++)
  239.         {
  240.             if (colmask[color] & (1 << i))
  241.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  242.         }
  243.     }
  244.  
  245.  
  246.     pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
  247.  
  248.     for (color = 0;color < 16;color++) colmask[color] = 0;
  249.  
  250.     for (offs = 0;offs < spriteram_size;offs += 8)
  251.     {
  252.         int flags = spriteram[offs+3];
  253.         int bank = spriteram[offs+0];
  254.         if( bank & 4 )
  255.         { /* visible */
  256.             int which = spriteram[offs+1];
  257.             int size = (spriteram[offs + 2] & 3);
  258.             /* 0 = 8x8 1 = 16x16 2 = 32x32 3 = 64x64 */
  259.             if (size == 3) continue;    /* not used by these games */
  260.  
  261.  
  262.             if( video_type != 0 )
  263.                 code = (which) + ((bank&0xf8)<<5); /* silkworm */
  264.             else
  265.                 code = (which)+((bank&0xf0)<<4); /* rygar */
  266.  
  267.             if (size == 1) code >>= 2;
  268.             else if (size == 2) code >>= 4;
  269.  
  270.             color = flags&0xf;
  271.  
  272.             colmask[color] |= Machine->gfx[size+1]->pen_usage[code];
  273.         }
  274.     }
  275.  
  276.     for (color = 0;color < 16;color++)
  277.     {
  278.         if (colmask[color] & (1 << 0))
  279.             palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
  280.         for (i = 1;i < 16;i++)
  281.         {
  282.             if (colmask[color] & (1 << i))
  283.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  284.         }
  285.     }
  286.  
  287.  
  288.     pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
  289.  
  290.     for (color = 0;color < 16;color++) colmask[color] = 0;
  291.  
  292.     for (offs = tecmo_videoram2_size - 1;offs >= 0;offs--)
  293.     {
  294.         code = tecmo_videoram2[offs] + ((tecmo_colorram2[offs] & 0x03) << 8);
  295.         color = tecmo_colorram2[offs] >> 4;
  296.         colmask[color] |= Machine->gfx[0]->pen_usage[code];
  297.     }
  298.  
  299.     for (color = 0;color < 16;color++)
  300.     {
  301.         for (i = 1;i < 16;i++)
  302.         {
  303.             if (colmask[color] & (1 << i))
  304.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  305.         }
  306.     }
  307. }
  308.  
  309. if (palette_recalc())
  310. {
  311.     memset(dirtybuffer,1,videoram_size);
  312.     memset(dirtybuffer2,1,videoram_size);
  313. }
  314.  
  315.  
  316.     /* draw the background. */
  317.     for (offs = videoram_size - 1;offs >= 0;offs--)
  318.     {
  319.         if (dirtybuffer[offs])
  320.         {
  321.             int code,color,sx,sy;
  322.  
  323.             if (video_type == 2)    /* Gemini Wing */
  324.             {
  325.                 code = videoram[offs] + 16 * (colorram[offs] & 0x70);
  326.                 color = colorram[offs] & 0x0f;
  327.             }
  328.             else
  329.             {
  330.                 code = videoram[offs] + 256 * (colorram[offs] & 0x07),
  331.                 color = colorram[offs] >> 4;
  332.             }
  333.             sx = offs % 32;
  334.             sy = offs / 32;
  335.  
  336.             drawgfx(tmpbitmap2,Machine->gfx[5],
  337.                     code,
  338.                     color,
  339.                     0,0,
  340.                     16*sx,16*sy,
  341.                     0,TRANSPARENCY_NONE,0);
  342.  
  343.             dirtybuffer[offs] = 0;
  344.         }
  345.  
  346.         if (dirtybuffer2[offs])
  347.         {
  348.             int code,color,sx,sy;
  349.  
  350.             if (video_type == 2)    /* Gemini Wing */
  351.             {
  352.                 code = tecmo_videoram[offs] + 16 * (tecmo_colorram[offs] & 0x70);
  353.                 color = tecmo_colorram[offs] & 0x0f;
  354.             }
  355.             else
  356.             {
  357.                 code = tecmo_videoram[offs] + 256 * (tecmo_colorram[offs] & 0x07),
  358.                 color = tecmo_colorram[offs] >> 4;
  359.             }
  360.             sx = offs % 32;
  361.             sy = offs / 32;
  362.  
  363.             drawgfx(tmpbitmap3,Machine->gfx[4],
  364.                     code,
  365.                     color,
  366.                     0,0,
  367.                     16*sx,16*sy,
  368.                     0,TRANSPARENCY_NONE,0);
  369.         }
  370.         dirtybuffer2[offs] = 0;
  371.     }
  372.  
  373.  
  374.     /* copy the temporary bitmap to the screen */
  375.     {
  376.         int scrollx,scrolly;
  377.  
  378.         /* draw background tiles */
  379.         scrollx = -tecmo_scroll[3] - 256 * (tecmo_scroll[4] & 1) - 48;
  380.         scrolly = -tecmo_scroll[5];
  381.  
  382.         copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,
  383.                 &Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  384.         /* sprites will be drawn with TRANSPARENCY_THROUGH and appear behind the background */
  385.         tecmo_draw_sprites( bitmap,3 ); /* this should never draw anything, but just in case... */
  386.  
  387.         tecmo_draw_sprites( bitmap,2 );
  388.  
  389.         /* draw foreground tiles */
  390.         scrollx = -tecmo_scroll[0] - 256 * (tecmo_scroll[1] & 1) - 48;
  391.         scrolly = -tecmo_scroll[2];
  392.         copyscrollbitmap(bitmap,tmpbitmap3,1,&scrollx,1,&scrolly,
  393.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  394.     }
  395.  
  396.     tecmo_draw_sprites( bitmap,1 );
  397.  
  398.     /* draw the frontmost playfield. They are characters, but draw them as sprites */
  399.     for (offs = tecmo_videoram2_size - 1;offs >= 0;offs--)
  400.     {
  401.         int sx = offs % 32;
  402.         int sy = offs / 32;
  403.  
  404.         drawgfx(bitmap,Machine->gfx[0],
  405.                 tecmo_videoram2[offs] + ((tecmo_colorram2[offs] & 0x03) << 8),
  406.                 tecmo_colorram2[offs] >> 4,
  407.                 0,0,
  408.                 8*sx,8*sy,
  409.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  410.     }
  411.  
  412.     tecmo_draw_sprites( bitmap,0 );
  413. }
  414.